---
title: 读取HBase表数据
---

Apache HBase是Hadoop上的分布式、版本化的非关系型数据库。

PXF HBase连接器读取存储在HBase表中的数据。HBase连接器支持过滤器下推。

本节介绍如何使用PXF HBase连接器

## <a id="prereq"></a>先决条件

使用HBase表数据前，请确保您已满足：

- 将 `$GPHOME/pxf/lib/pxf-hbase-*.jar` 复制到HBase集群中的每个节点，并且该PXF JAR文件位于 `$HBASE_CLASSPATH` 中。 PXF HBase 连接器需要此配置才能支持过滤器下推。
- 满足PXF Hadoop [先决条件](access_hdfs.html#hadoop_prereq).

## <a id="hbase_primer"></a>HBase入门

本主题假设您对以下HBase概念有基本的了解：
 
- HBase 列包含两个组件：列簇和列限定词。 这些组件由冒号 `:` 分隔， \<column-family\>:\<column-qualifier\>
- HBase 行由一个行键和一个或多个列值组成。 行键是表行的唯一标识符
- HBase 表是由具有一个或多个列的数据行组成的多维映射。 创建HBase表时，可以指定一组完整的列簇
- HBase 单元由行(列簇, 列限定词, 列值)和时间戳组成。 给定单元格中的列值和时间戳表示该值的版本

有关HBase的详细信息，请参阅[Apache HBase Reference Guide](http://hbase.apache.org/book.html)。

## <a id="hbase_shell"></a>HBase Shell

HBase shell 是一个类似 `psql` 的子系统。 要启动HBase shell：

``` shell
$ hbase shell
<hbase output>
hbase(main):001:0>
```

HBase默认的命名空间为 `default`。

### <a id="hbaseshell_example" class="no-quick-link"></a>示例: 创建一个HBase表

创建一个示例HBase表。

1. 在 `default` 命名空间中创建一个名为 `order_info` 的HBase表。 `order_info` 具有两个列簇: `product` 和 `shipping_info`：

    ``` pre
    hbase(main):> create 'order_info', 'product', 'shipping_info'
    ```

2. `order_info` `product` 列簇具有名为 `name` 和 `location` 的列标识符。 `shipping_info` 列簇具有名为 `state` 和 `zipcode` 的列标识符。 将一些数据添加到 `order_info` 表中：

    ``` pre
    put 'order_info', '1', 'product:name', 'tennis racquet'
    put 'order_info', '1', 'product:location', 'out of stock'
    put 'order_info', '1', 'shipping_info:state', 'CA'
    put 'order_info', '1', 'shipping_info:zipcode', '12345'
    put 'order_info', '2', 'product:name', 'soccer ball'
    put 'order_info', '2', 'product:location', 'on floor'
    put 'order_info', '2', 'shipping_info:state', 'CO'
    put 'order_info', '2', 'shipping_info:zipcode', '56789'
    put 'order_info', '3', 'product:name', 'snorkel set'
    put 'order_info', '3', 'product:location', 'warehouse'
    put 'order_info', '3', 'shipping_info:state', 'OH'
    put 'order_info', '3', 'shipping_info:zipcode', '34567'
    ```
    
    在本主题后面的示例中，您将通过PXF直接访问 `orders_info` HBase 表。

3. 显示 `order_info` 表的内容：

    ``` pre
    hbase(main):> scan 'order_info'
    ROW     COLUMN+CELL                                               
     1      column=product:location, timestamp=1499074825516, value=out of stock                                                
     1      column=product:name, timestamp=1499074825491, value=tennis racquet                                                  
     1      column=shipping_info:state, timestamp=1499074825531, value=CA                                                       
     1      column=shipping_info:zipcode, timestamp=1499074825548, value=12345                                                  
     2      column=product:location, timestamp=1499074825573, value=on floor    
     ... 
    3 row(s) in 0.0400 seconds                                         
    ```

## <a id="syntax3"></a>查询外部HBase数据

PXF HBase 连接器支持一个名为的 `HBase` 的配置文件。

使用以下语法创建引用HBase表的Greenplum数据库外部表：

``` sql
CREATE EXTERNAL TABLE <table_name>
    ( <column_name> <data_type> [, ...] | LIKE <other_table> )
LOCATION ('pxf://<hbase-table-name>?PROFILE=HBase')
FORMAT 'CUSTOM' (FORMATTER='pxfwritable_import');
```

[CREATE EXTERNAL TABLE](../ref_guide/sql_commands/CREATE_EXTERNAL_TABLE.html) 命令中HBase连接器使用的特定关键字和值见下表描述。

| 关键字  | 值 |
|-------|-------------------------------------|
| \<hbase&#8209;table&#8209;name\>    | HBase表的名称 |
| PROFILE    | `PROFILE` 关键字必须指定为 `HBase` |
| FORMAT  | `FORMAT` 子句必须指定为 `'CUSTOM' (FORMATTER='pxfwritable_import')`   |



## <a id="datatypemapping"></a>数据类型映射

HBase是基于字节的; 它将所有数据类型存储为字节数组。 要在Greenplum数据库中表示HBase数据，请为Greenplum数据库列选择与HBase列标识符值的底层内容匹配的数据类型。

**注意**: PXF不支持复杂HBase对象


## <a id="columnmapping"></a>列映射

您可以创建一个引用HBase表定义中全部或部分列标识符的Greenplum数据库外部表。PXF支持Greenplum数据库表列和HBase表列标识符之间的直接或间接映射。

### <a id="directmapping" class="no-quick-link"></a>直接映射

当您使用直接映射将Greenplum数据库外部表的列名映射到HBase标识符时，您可以将列簇限定的HBase标识符名称指定为带引号的值。 PXF HBase连接器在读取表数据时将这些列名按原样传递给HBase。

例如, 创建一个访问以下数据的Greenplum数据库外部表：

-   列簇 `product` 中的 `name` 标识符
-   列簇 `shipping_info` 中的 `zipcode` 标识符

从此前您在[示例: 创建一个HBase表](#hbaseshell_example) 创建的 `order_info` HBase 表中访问数据，使用以下 `CREATE EXTERNAL TABLE` 语法：

``` sql
CREATE EXTERNAL TABLE orderinfo_hbase ("product:name" varchar, "shipping_info:zipcode" int)
    LOCATION ('pxf://order_info?PROFILE=HBase')                                     
    FORMAT 'CUSTOM' (FORMATTER='pxfwritable_import');
```

### <a id="indirectmappingvialookuptable" class="no-quick-link"></a>通过查找表间接映射

当您使用间接映射将Greenplum数据库外部表列名映射到HBase标识符时，您可以在HBase中创建的查找表中指定映射。 查找表将 \<column-family\>:\<column-qualifier\> 映射到在创建Greenplum数据库外部表时指定的列名别名。

您必须将HBase PXF查找表命名为 `pxflookup` 。 并且您必须使用一个名为 `mapping` 的单列簇定义此表。例如:

``` pre
hbase(main):> create 'pxflookup', 'mapping'
```

尽管直接映射既快速又直观， 使用间接映射可以让您为HBase \<column-family\>:\<column-qualifier\> 名称创建一个较短的，基于字符的别名。由于以下原因，这可以更好的使HBase标识符与Greenplum数据库保持一致:

-   HBase 标识符可能非常长。 Greenplum数据库列名大小限制为63各字符。
-   HBase 标识符名称可以包含二进制或不可打印的字符。 Greenplum数据库列名称是基于字符的。

填充 `pxflookup` HBase表时, 向表中添加行, 以便:

- 行键指定为HBase表名
- `mapping` 列簇标识符定义为Greenplum数据库列名, 值标识为需要创建别名的HBase `<column-family>:<column-qualifier>`

例如，要在 `order_info` 表上使用间接映射，将以下条目添加到 `pxflookup` 表：

``` pre
hbase(main):> put 'pxflookup', 'order_info', 'mapping:pname', 'product:name'
hbase(main):> put 'pxflookup', 'order_info', 'mapping:zip', 'shipping_info:zipcode'
```

使用以下 `CREATE EXTERNAL TABLE` 语法创建Greenplum数据库外部表

``` sql
CREATE EXTERNAL TABLE orderinfo_map (pname varchar, zip int)
    LOCATION ('pxf://order_info?PROFILE=HBase')
    FORMAT 'CUSTOM' (FORMATTER='pxfwritable_import');
```

## <a id="rowkey"></a>行键

HBase 表行键是表行的唯一标识符。 PXF 以特殊方式处理行键。

要在Greenplum数据库外部表查询中使用行键，请使用名为 `recordkey` 的PXF保留列定义外部表。 `recordkey` 列名指示PXF返回每一行的HBase表记录键。

使用Greenplum数据库数据类型`bytea` 定义 `recordkey`

例如:

``` sql
CREATE EXTERNAL TABLE <table_name> (recordkey bytea, ... ) 
    LOCATION ('pxf://<hbase_table_name>?PROFILE=HBase')
    FORMAT 'CUSTOM' (FORMATTER='pxfwritable_import');
```

在您创建外部表之后，您可以在 `WHERE` 子句中使用 `recordkey` 在一系列键值上过滤HBase表

**注意**: 若要在 `recordkey` 上启用过滤器下推，请将字段定义为 `text`
